﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Text;

using Yukkrile;
using System.Runtime.Remoting.Channels.Ipc;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;
using System.Threading;

namespace YukkFront
{
    class Program : ApplicationContext
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Program());
        }


        static bool Alive = true;
        static int Ratio = 120;
        static System.Windows.Forms.Form parent;
        static object strqLocker = new object();
        static FinishInfo translator = null;
        static Queue<string> stringQueue = new Queue<string>();
        private Program()
        {
            try
            {
                parent = new System.Windows.Forms.Form();
                AquesTalk.AquesTalk.Instance.SetParentWindowForm(parent);
                AquesTalk.AquesTalk.Instance.InitImeSvc();
                AquesTalk.AquesTalk.Instance.LoadReplaceTables();

                //このチャネル生成系は一度通せばいいっぽい
                // IPC Channelを作成
                IpcServerChannel servChannel = new IpcServerChannel("krileyukkrilesub");
                // リモートオブジェクトを登録

                ChannelServices.RegisterChannel(servChannel, true);

                // イベントを登録
                var m_msg = new TalkRequestInfo();
                m_msg.OnTrance += new TalkRequestInfo.CallEventHandler(m_msg_OnTrance);
                RemotingServices.Marshal(m_msg, "message", typeof(TalkRequestInfo));

                //このチャネル生成系は一度通せばいいっぽい
                // IPC Channel を作成
                IpcClientChannel clientChannel = new IpcClientChannel();
                // リモートオブジェクトを登録
                ChannelServices.RegisterChannel(clientChannel, true);
                // オブジェクトを作成
                translator = (FinishInfo)Activator.GetObject(typeof(FinishInfo), "ipc://krileyukkrilesubrecv/message");

                var src = "すてー'たす/よみあげ/さぽーと/ぷらぐ'いん、ゆっく'るる。ばーじょん、<NUMK VAL=" + Define.Version + ">が、よみこまれ'ました。";
                var ret = AquesTalk.AquesTalk.Instance.Speak(src, Ratio);

                while (Alive)
                {
                    Thread.Sleep(0);
                    if (stringQueue.Count > 0)
                    {
                        lock (strqLocker)
                        {
                            while (stringQueue.Count > 0)
                            {
                                var source = stringQueue.Dequeue();
                                var result = AquesTalk.AquesTalk.Instance.Talk(source, Ratio);
                                translator.ReadFinished(result, AquesTalk.AquesTalk.Instance.GetErrorText(result));
                            }
                        }
                    }
                }
                this.ExitThread();
            }
            catch (Exception e)
            {
                MessageBox.Show(
                    "Yukkrile フロントエンド YukkFrontでエラーが発生しました:" + Environment.NewLine +
                    e.ToString());
                throw;
            }
        }

        static void m_msg_OnTrance(TalkRequestInfo.TalkInfoEventArg e)
        {
            Ratio = e.Ratio;
            if (e.String == TalkRequestInfo.TableReloadString)
            {
                AquesTalk.AquesTalk.Instance.LoadReplaceTables();
                translator.ReadFinished(0, null);
            }
            else
            {
                lock (strqLocker)
                {
                    stringQueue.Enqueue(e.String);
                }
            }
        }
    }
}
